home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / RevRdist Folder / RevRdist / RevRdist src / junkf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  7.3 KB  |  307 lines  |  [TEXT/KAHL]

  1. /*
  2.  * junkf.c - routines for manipulating the "junk" folder
  3.  */
  4. #include "RevRdist.h"
  5. #include "dispatch.h"
  6. #include "TransSkelProto.h"
  7. #include "TransDisplayProto.h"
  8. #include "desktop.h"
  9.  
  10. /*
  11.  * prototype for local function
  12.  */
  13. static Integer testJunk(cnode_t *);
  14.  
  15. /*
  16.  *=========================================================================
  17.  * cleanJunk () - get rid of old files in "junk" folder
  18.  *=========================================================================
  19.  */
  20.  
  21. DISPATCHED (cleanJunk)
  22. {
  23.     struct lm                        /* local memory */
  24.     {
  25.         frame_t            f;
  26.     };
  27.     typedef struct lm    lm_t;
  28.     register lm_t *        m;            /* pointer to local memory */
  29.     file_info_t *        fi;            /* ptr to junk entry in File_list[] */
  30.     StringPtr            p;            /* temp */
  31.     Ptr                    paramv[2];
  32.     short                result;        /* our result */
  33.     StringHandle        sh;            /* temp */
  34.  
  35.     m = *(lm_t **)fh;
  36.     result = request;
  37.     switch (request)
  38.     {
  39.     case R_INIT:
  40.         if (ClueID = resizeFrame (fh, sizeof (lm_t)))
  41.             return R_ERROR;
  42.         m = *(lm_t **)fh;
  43.         m->f.state = 1;
  44.         return R_CONT;
  45.  
  46.     case R_CONT:
  47.         /*
  48.          * The bulk of the work is just setting up for emptyFolder.
  49.          * Everything is done in state 1.
  50.          */
  51.         fi = &File_list[FL_JUNK];
  52.         if (m->f.state == 1)
  53.         {
  54.             if (fi->f_vol == 0 || fi->f_set == 0)
  55.             {
  56.                 /*
  57.                  * Mention it if there is no junk folder
  58.                  */
  59.                 if (sh = Prefs[P_WORK].p[PS_JUNKF])
  60.                 {
  61.                     HLock ((Handle)sh);
  62.                     p = *sh;
  63.                 }
  64.                 else
  65.                     p = "\p<unknown>";
  66.                 dispIndStr (ActivityWind, L_SKIP, LST_STR, p, nil);
  67.                 result = R_CONT;
  68.                 if (sh)
  69.                     HUnlock ((Handle)sh);
  70.                 result = popCall (R_CONT, nil);
  71.                 break;
  72.             }
  73.             /*
  74.              * Tell 'em what we're doing
  75.              */
  76.             if (Flags & PF_VERBOSE)
  77.             {
  78.                 sh = fi->f_path;
  79.                 HLock ((Handle)sh);
  80.                 dispIndStr (ActivityWind, L_DOJUNK, LST_STR, *sh, nil);
  81.                 HUnlock ((Handle)sh);
  82.             }
  83.             /*
  84.              * Use the File_list catalog entry for junk folder for emptyFolder()
  85.              */
  86.             m->f.state = 2;
  87.             paramv[0] = (Ptr)&fi->f_info;
  88.             paramv[1] = (Ptr)testJunk;
  89.             return (pushCall (emptyFolder, paramv));
  90.         }
  91.         else if (m->f.state == 2)
  92.         {
  93.             m->f.state = 3;
  94.             return result;            /* just allow emptyFolder to exit */
  95.         }
  96.         /*
  97.          * Else, fall into
  98.          */
  99.     default:
  100.         result = popCall (result, nil);
  101.         break;
  102.     }
  103.     return result;
  104. }
  105.  
  106.  
  107.  
  108. /*
  109.  *=========================================================================
  110.  * makeJunk () - create junk folder
  111.  * entry:    junk folder name given by preferences string
  112.  * returns:    OSErr
  113.  *=========================================================================
  114.  */
  115.  
  116.  
  117. OSErr
  118. makeJunk ()
  119. {
  120.     OSErr                error;
  121.     file_info_t *        fi;            /* ptr into File_list for junk folder */
  122.     StringHandle        sh;            /* name of junk folder */
  123.     HParamBlockRec        hpb;        /* for PBDirCreate, etc */
  124.     Str255                s;            /* string temp */
  125.  
  126.     error = fnfErr;
  127.     s[0] = 0;
  128.     sh = Prefs[P_WORK].p[PS_JUNKF];
  129.     while (sh && **sh)                /* "while" is so can use "break" */
  130.     {
  131.         /*
  132.          * We always try to create the junk folder, even though that will
  133.          * often fail.  But it's just as fast as checking to see if the
  134.          * folder exists.
  135.          */
  136.         COPYPS (*sh, s);
  137.         ZERO (hpb);
  138.         hpb.fileParam.ioNamePtr = s;
  139.         hpb.fileParam.ioVRefNum = ClientVol;
  140.         hpb.fileParam.ioDirID = ClientRoot;
  141.         error = PBDirCreate (&hpb, false);
  142.         switch (error)
  143.         {
  144.         case noErr:                    /* folder created */
  145.             break;
  146.         case vLckdErr:                /* if volume locked, switch to LISTONLY */
  147.         case wPrErr:
  148.             Flags |= PF_LISTONLY;
  149.             /* fall into ... */
  150.         case dupFNErr:                /* if already exists, not an error */
  151.             error = 0;
  152.             break;
  153.         }
  154.         if (error)                    /* if trouble already */
  155.             break;
  156.         fi = &File_list[FL_JUNK];
  157.         fi->f_ref = 0;
  158.         fi->f_vol = ClientVol;
  159.         error = getInfoByPath (s, fi);
  160.         break;
  161.     }
  162.     if (error)
  163.     {
  164.         warning (E_NOJUNK, s, nil);
  165.         error = 0;
  166.     }
  167.     return error;
  168. }
  169.  
  170.  
  171.  
  172. /*
  173.  *=========================================================================
  174.  * moveToJunk (cp) - move file/folder to junk folder
  175.  * entry:    cp = pointer to client catalog list node
  176.  * returns:    0 on success, else OSErr
  177.  *=========================================================================
  178.  */
  179. OSErr
  180. moveToJunk (cp)
  181. register cnode_t *    cp;
  182. {
  183.     OSErr            error;
  184.     file_info_t *    fi;                    /* ptr to File_list for junk */
  185.     int                i,j;                /* temps */
  186.     StringPtr        s;
  187.     CMovePBRec        cpb;                /* PBCatMove param block */
  188.     HParamBlockRec    pb;                    /* PBHRename param block */
  189.     Byte            junkname[32];        /* new name for existing junk file */
  190.  
  191.     fi = &File_list[FL_JUNK];
  192.     if (fi->f_set == 0)
  193.     {
  194.         /* if no junk directory, skip it */
  195.         notice (L_SKPJUNK, cp->name, nil);
  196.         return 0;
  197.     }
  198.     if (cp->dirID == fi->f_info.dirID)
  199.         return 0;                    /* cannot move junk into itself */
  200.     notice (L_JUNKING, cp->name, nil);
  201.     if (Flags & PF_LISTONLY)
  202.         return 0;
  203.     desktop_remove(cp);
  204. retry:
  205.     ZERO (cpb);
  206.     cpb.ioNamePtr = cp->name;
  207.     cpb.ioVRefNum = ClientVol;
  208.     cpb.ioDirID = cp->parID;
  209.     cpb.ioNewName = fi->f_info.name;
  210.     cpb.ioNewDirID = fi->f_info.parID;
  211.     error = PBCatMove (&cpb, false);
  212.     s = "\pPBCatMove";
  213.     /*
  214.      * If the move fails, it might be because there is already something
  215.      * there by the same name.  If so, rename the existing file/folder
  216.      * and try moving again.
  217.      */
  218.     if (error == dupFNErr)
  219.     {
  220.         COPYPS (cp->name, junkname);
  221.         do
  222.         {
  223.             /*
  224.              * We try several possible names to rename the conflicting
  225.              * file/folder out of the way.
  226.              * The first is just to append the Junksuf string to the name.
  227.              * If that won't fit, we replace the end of the name with
  228.              * Junksuf.
  229.              * If the result still conflicts, we increment the last character
  230.              * of the name until we get no conflict or we run out of
  231.              * "nice" characters, where "nice" is defined as "differing
  232.              * from the last char of Junksuf only in the low 5 bits".
  233.              */
  234.             j = Junksuf[0];
  235.             i = junkname[0];
  236.             if (i < 31)
  237.             {
  238.                 if (i + j > 31)
  239.                     i = 31 - j;
  240.                 junkname[0] = i + j;
  241.                 for (;j;j--)
  242.                     junkname[i+j] = Junksuf[j];
  243.             }
  244.             else
  245.             {
  246.                 j = junkname[i];
  247.                 if ((j & 0x1f) != 0x1f)
  248.                     junkname[i] = j+1;
  249.                 else
  250.                     return error;
  251.             }
  252.             ZERO (pb);
  253.             pb.ioParam.ioNamePtr = cp->name;
  254.             pb.ioParam.ioVRefNum = ClientVol;
  255.             pb.ioParam.ioMisc = (Ptr) junkname;
  256.             pb.fileParam.ioDirID = fi->f_info.dirID;
  257.             error = PBHRename (&pb, false);
  258.             s = "\pPBHRename";
  259.         } while (error == dupFNErr);
  260.         if (error == 0)
  261.             goto retry;
  262.     }
  263.     if (error)
  264.     {
  265.         ClueID = error;
  266.         notice (L_SYS, "\pmoveToJunk", (SP) s, nil);
  267.     }
  268.     else
  269.         statMsgClr ();
  270.     return error;
  271. }
  272.  
  273.  
  274.  
  275. /*
  276.  *=========================================================================
  277.  * testJunk (cp) - decide if file/folder should be discarded from junk
  278.  * entry:    cp = pointer to catalog list entry for file/folder
  279.  *            Junkp, ClientSp set
  280.  * returns:    0 if file/folder should not be discarded
  281.  *            <> 0 if it should
  282.  *=========================================================================
  283.  */
  284. static
  285. Integer
  286. testJunk (cp)
  287. register cnode_t *    cp;
  288. {
  289. register Integer    result;
  290.     static unsigned long now = 0;
  291.  
  292.     if (now == 0)
  293.         GetDateTime (&now);
  294.     if (cp->ctype == C_FOLDER)
  295.         result = true;                /* always junk (contents of) folders */
  296.     else if (cp->mdDate + Prefs[P_WORK].p_jparam.max < now)
  297.         result = true;                /* if modified long ago */
  298.     else if (now + Prefs[P_WORK].p_jparam.max < cp->mdDate)
  299.         result = true;                /* if modified long in the future ??? */
  300.     else if (cp->mdDate + Prefs[P_WORK].p_jparam.min > now)
  301.         result = false;                /* if changed recently */
  302.     else if (ClientSp < Prefs[P_WORK].p_jparam.space)
  303.         result = true;                /* if short on space */
  304.     else
  305.         result = false;
  306.     return result;
  307. }